package com.ffggffgfv.backend.service.impl;

import com.ffggffgfv.backend.dto.PageResult;
import com.ffggffgfv.backend.dto.UserLoginDTO;
import com.ffggffgfv.backend.dto.UserRegisterDTO;
import com.ffggffgfv.backend.dto.UserUpdateDTO;
import com.ffggffgfv.backend.entity.User;
import com.ffggffgfv.backend.mapper.UserMapper;
import com.ffggffgfv.backend.service.UserRoleService;
import com.ffggffgfv.backend.service.UserService;
import com.ffggffgfv.backend.util.AESUtil;
import com.ffggffgfv.backend.util.BCryptUtil;
import com.ffggffgfv.backend.util.JWTUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;

/**
 * 用户服务实现类
 */
@Service
public class UserServiceImpl implements UserService {

    private static final Logger logger = Logger.getLogger(UserServiceImpl.class.getName());

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private UserRoleService userRoleService;

    @Autowired
    private JWTUtil jwtUtil;

    @Autowired
    private BCryptPasswordEncoder passwordEncoder;

    @Override
    public List<User> findAll() {
        return userMapper.selectAll();
    }

    @Override
    public User register(UserRegisterDTO userRegisterDTO) {
        User user = new User();
        user.setUsername(userRegisterDTO.getUsername());
        user.setPhone(AESUtil.encrypt(userRegisterDTO.getPhone()));
        user.setEmail(userRegisterDTO.getEmail());
        user.setPassword(BCryptUtil.encode(userRegisterDTO.getPassword()));
        user.setAvatarUrl(userRegisterDTO.getAvatarUrl());
        user.setCreateTime(LocalDateTime.now());
        user.setUpdateTime(LocalDateTime.now());

        userMapper.insert(user);

        user.setPassword(null);
        return user;
    }

    @Override
    public boolean isUsernameExists(String username) {
        return userMapper.selectByUsername(username) != null;
    }

    @Override
    public boolean isPhoneExists(String phone) {
        String encryptedPhone = AESUtil.encrypt(phone);
        return userMapper.selectByPhone(encryptedPhone) != null;
    }

    @Override
    public boolean isEmailExists(String email) {
        return userMapper.selectByEmail(email) != null;
    }

    @Override
    public Map<String, Object> login(UserLoginDTO userLoginDTO) {
        User user = null;

        if (userLoginDTO.getLoginType() == 1) {
            if (userLoginDTO.getUsername() != null && !userLoginDTO.getUsername().trim().isEmpty()) {
                user = userMapper.selectByUsername(userLoginDTO.getUsername());
            }

            if (user == null && userLoginDTO.getPhone() != null && !userLoginDTO.getPhone().trim().isEmpty()) {
                String encryptedPhone = AESUtil.encrypt(userLoginDTO.getPhone());
                user = userMapper.selectByPhone(encryptedPhone);
            }

            if (user == null || !BCryptUtil.matches(userLoginDTO.getPassword(), user.getPassword())) {
                return null;
            }
        } else if (userLoginDTO.getLoginType() == 2) {
            String correctCode = "0000";

            if (!correctCode.equals(userLoginDTO.getVerifyCode())) {
                return null;
            }

            String encryptedPhone = AESUtil.encrypt(userLoginDTO.getPhone());
            user = userMapper.selectByPhone(encryptedPhone);

            if (user == null) {
                return null;
            }
        } else {
            return null;
        }

        // 由于user_role表暂未创建，先使用默认角色
        List<String> roleCodes = new ArrayList<>();
        roleCodes.add("ROLE_USER"); // 默认添加普通用户角色

        String token = jwtUtil.generateToken(user.getId(), user.getUsername());

        user.setPassword(null);
        user.setPhone(AESUtil.decrypt(user.getPhone()));

        Map<String, Object> result = new HashMap<>();
        result.put("user", user);
        result.put("token", token);
        result.put("roles", roleCodes);

        return result;
    }

    @Override
    public User findById(Long id) {
        User user = userMapper.selectById(id);
        if (user != null) {
            try {
                String decryptedPhone = AESUtil.decrypt(user.getPhone());
                user.setPhone(decryptedPhone);
            } catch (Exception e) {
                logger.warning("解密手机号失败，用户ID: " + id + ", 原因: " + e.getMessage());
            }
            user.setPassword(null);
        }
        return user;
    }

    @Override
    public User findByUsername(String username) {
        return userMapper.selectByUsername(username);
    }

    @Override
    public User findByPhone(String phone) {
        return userMapper.selectByPhone(phone);
    }

    @Override
    public User findByEmail(String email) {
        return userMapper.selectByEmail(email);
    }

    @Override
    public PageResult<User> findByPage(String username, int pageNum, int pageSize) {
        int offset = (pageNum - 1) * pageSize;
        long total = userMapper.countAll(username);
        List<User> users = userMapper.selectByPage(username, offset, pageSize);
        return new PageResult<>(users, total, pageNum, pageSize);
    }

    @Override
    public User createUser(User user) {
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        LocalDateTime now = LocalDateTime.now();
        user.setCreateTime(now);
        user.setUpdateTime(now);
        userMapper.insert(user);
        return user;
    }

    @Override
    public User updateUser(Long id, UserUpdateDTO userUpdateDTO) {
        User user = userMapper.selectById(id);
        if (user == null) {
            return null;
        }

        boolean needUpdate = false;

        if (userUpdateDTO.getPhone() != null && !userUpdateDTO.getPhone().trim().isEmpty()) {
            String encryptedPhone = AESUtil.encrypt(userUpdateDTO.getPhone());
            User phoneUser = userMapper.selectByPhone(encryptedPhone);
            if (phoneUser != null && !phoneUser.getId().equals(id)) {
                logger.warning("手机号已被使用，用户ID: " + id);
                return null;
            }
            user.setPhone(encryptedPhone);
            needUpdate = true;
        }

        if (userUpdateDTO.getEmail() != null) {
            if (!userUpdateDTO.getEmail().trim().isEmpty()) {
                User emailUser = userMapper.selectByEmail(userUpdateDTO.getEmail());
                if (emailUser != null && !emailUser.getId().equals(id)) {
                    logger.warning("邮箱已被使用，用户ID: " + id);
                    return null;
                }
            }
            user.setEmail(userUpdateDTO.getEmail());
            needUpdate = true;
        }

        if (userUpdateDTO.getAvatarUrl() != null) {
            user.setAvatarUrl(userUpdateDTO.getAvatarUrl());
            needUpdate = true;
        }

        if (userUpdateDTO.getOldPassword() != null && !userUpdateDTO.getOldPassword().isEmpty() &&
                userUpdateDTO.getNewPassword() != null && !userUpdateDTO.getNewPassword().isEmpty()) {
            if (!BCryptUtil.matches(userUpdateDTO.getOldPassword(), user.getPassword())) {
                logger.warning("旧密码验证失败，用户ID: " + id);
                return null;
            }
            user.setPassword(BCryptUtil.encode(userUpdateDTO.getNewPassword()));
            needUpdate = true;
        }

        if (needUpdate) {
            user.setUpdateTime(LocalDateTime.now());
            userMapper.update(user);
        }

        user.setPassword(null);

        if (user.getPhone() != null) {
            try {
                user.setPhone(AESUtil.decrypt(user.getPhone()));
            } catch (Exception e) {
                logger.warning("解密手机号失败，用户ID: " + id + ", 原因: " + e.getMessage());
            }
        }

        return user;
    }

    @Override
    public User updateUser(Long id, User user) {
        User existingUser = userMapper.selectById(id);
        if (existingUser == null) {
            return null;
        }

        user.setId(id);
        user.setUpdateTime(LocalDateTime.now());
        user.setPassword(existingUser.getPassword());
        user.setCreateTime(existingUser.getCreateTime());
        userMapper.update(user);

        return userMapper.selectById(id);
    }

    @Override
    public boolean updatePassword(Long id, String oldPassword, String newPassword) {
        User user = userMapper.selectById(id);
        if (user == null) {
            return false;
        }

        if (!passwordEncoder.matches(oldPassword, user.getPassword())) {
            return false;
        }

        user.setPassword(passwordEncoder.encode(newPassword));
        user.setUpdateTime(LocalDateTime.now());
        userMapper.updatePassword(id, user.getPassword(), user.getUpdateTime());

        return true;
    }

    @Override
    public Map<String, Object> getUserDetail(Long id) {
        User user = findById(id);
        if (user == null) {
            return null;
        }

        Map<String, Object> userDetail = new HashMap<>();
        userDetail.put("id", user.getId());
        userDetail.put("username", user.getUsername());
        userDetail.put("phone", user.getPhone());
        userDetail.put("email", user.getEmail());
        userDetail.put("avatarUrl", user.getAvatarUrl());
        userDetail.put("createTime", user.getCreateTime());

        return userDetail;
    }
}
